﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;

using System.Net;
using System.Net.NetworkInformation;

using TeamFoundationServerSensor;

public partial class _Default : System.Web.UI.Page {

    /// <summary>
    /// Timeout constant for pings.
    /// </summary>
    private const int timeout = 2000;

    /// <summary>
    /// Code that gets executed upon a page load.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e) {

        // Refresh page every five seconds
        string HomePageUrl = "Default.aspx";
        this.Page.Header.Controls.Add(new LiteralControl(string.Format(@" <META http-equiv='REFRESH' content=15;url={0}> ", HomePageUrl)));
            
        // Check if the sensor is running
        Boolean status = SensorShellControl.running();

        // Determine if the sensorshell is online and started correctly.
        if (status) {
            this.SensorStatus.ImageUrl = "~/Style/images/Online.png";
        }
        else {
            this.SensorStatus.ImageUrl = "~/Style/images/Offline.png";
        }

        // Ping the sensorsbase to see if it exists and is online.
        string sensorbaseURI = Settings.Instance.getSetting("Sensorbase");
        if (sensorbaseURI.Equals(String.Empty)) {
            this.SensorbaseStatus.ImageUrl = "~/Style/images/Unknown.png";
        }
        else if (ping(sensorbaseURI, "Sensorbase", "SensorBase")) {
            this.SensorbaseStatus.ImageUrl = "~/Style/images/Online.png";
        }
        else {
            this.SensorbaseStatus.ImageUrl = "~/Style/images/Offline.png";
        }


        try {
            // Ping the VSTFS server to determine if it is online.
            if (ping(Settings.Instance.getSetting("Server"), "VSTFS", null)
                && Connections.getNewTFSConnection().HasAuthenticated) {
                this.VSTFSStatus.ImageUrl = "~/Style/images/Online.png";
            }
            else {
                this.VSTFSStatus.ImageUrl = "~/Style/images/Offline.png";
            }
        }
        catch (Exception ex) {
            Logger.TheInstance.Log(ex);
            this.VSTFSStatus.ImageUrl = "~/Style/images/Offline.png";
        }
    }

    /// <summary>
    /// Required incase we cannot safely shutdown the webserver.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void ManualShutdown_Click(object sender, EventArgs e) {
        Global.stop("Manual Shutdown");
        this.Page.Response.Redirect(Page.Request.Url.ToString(), true);
    }

    /// <summary>
    /// USed to manually start the sensorshell if its offline.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void ManualStart_Click(object sender, EventArgs e) {
        Global.start();
        this.Page.Response.Redirect(Page.Request.Url.ToString(), true);
    }

    /// <summary>
    /// Runs a simple ping command to an application and returns the result.
    /// </summary>
    /// <param name="hostname">The hostname that is being pinged.</param>
    /// <param name="type">The type of host we are pinging.</param>
    /// <param name="expResponse">The expected response. Null if don't care.</param>
    /// <returns>True if the ping returned before time ran out. False otherwise.</returns>
    private Boolean ping(string hostname, string type, string expResponse) {
        try {

            // Double check hostname.
            if (hostname == null) {
                throw new ArgumentException("Bad hostname for ping.");
            }

            // Send the ping.
            Ping pinger = new Ping();
            IPHostEntry ip = Dns.GetHostEntry(hostname);
            PingReply reply = pinger.Send(ip.AddressList[0], timeout);

            // parse the reply.
            if (reply.Status == IPStatus.Success && (expResponse == null || 
                reply.Buffer.ToString().Equals(expResponse))) {
                return true;
            }
            else {
                Logger.TheInstance.Log(type + " ping error: " + reply.Status, 
                    LogLevel.Warning);
            }
        }
        catch (Exception e) {
            Logger.TheInstance.Log(e);
        }

        return false;
    }
}
